package com.auxiliary;

import java.util.ArrayList;
import java.util.List;

public class TimeCorrelation {
	
	private static int order = 12;
	
	//总体计算
	public static CorrelationLine calc(List<Double> referenceList, List<Double> analysisList) {
		CorrelationLine corRes = new CorrelationLine();
		
		corRes.setData(calcTimeCor(referenceList, analysisList));
		double max[] = findMax(corRes.getData());
		
		corRes.setEigenValue(max[0]);
		corRes.setEigenOrder((int)max[1]);
		
		return corRes;
	}
	
	//计算两个序列之间的时差相关系数
	private static List<Double> calcTimeCor(List<Double> baseList, List<Double> analysisList) {
		
		int size = baseList.size() < analysisList.size() ? baseList.size() : analysisList.size();
        List<Double> allCor = new ArrayList<Double>();
        for (int i = -order; i < 0; i++)
        {
            List<Double> tempBaseList = new ArrayList<Double>();
            for (int j = 0; j < size + i; j++)
            {
                tempBaseList.add(baseList.get(j - i));
            }

            allCor.add(calcBaseCor(tempBaseList, analysisList));

        }
        for (int i = 0; i <= order; i++)
        {
            List<Double> tempAnalysisList = new ArrayList<Double>();
            for (int j = 0; j < size - i; j++)
            {
                tempAnalysisList.add(analysisList.get(i + j));
            }
            allCor.add(calcBaseCor(baseList, tempAnalysisList));

        }
		
		return allCor;
	}
	
	//计算两个序列之间的时差相关系数
	private static double calcBaseCor(List<Double> list1, List<Double> list2) {
		
		if (list1 == null || list2 == null)
			return -2;
		
		int size = list1.size() < list2.size() ? list1.size() : list2.size();
		if(size == 0)
			return -2;
		
		double xy, xx, yy;
		double avg1 = 0;
		double avg2 = 0;
		xy = xx = yy = 0;
		
		for(int i = 0; i < size; i++) {
			avg1 += list1.get(i);
			avg2 += list2.get(i);
		}
		avg1 /= size;
		avg2 /= size;
		
		for(int i = 0; i < size; i++) {
			xy += (list1.get(i) - avg1) * (list2.get(i) - avg2);
			xx += (list1.get(i) - avg1) * (list1.get(i) - avg1);
			yy += (list2.get(i) - avg2) * (list2.get(i) - avg2);
		}
		
		return xy / Math.sqrt(xx * yy);
	}
	
	//计算最大时差相关系数对应的结束和数值
	private static double[] findMax(List<Double> allCor) {
		
		int maxOrder = -order;
        if (allCor == null)
        	return null;
        double maxCorrelation = allCor.get(0);
        for (int j = -order + 1; j < allCor.size() - order; j++)
        {
            if (Math.abs(allCor.get(j + order)) > Math.abs(maxCorrelation))
            {
                maxCorrelation = allCor.get(j + 12);
                maxOrder = j;
            }
        }
        
        return new double[]{maxCorrelation, (double)maxOrder};
	}
}
